package com.usoft;

import akka.dispatch.ExecutionContexts;
import akka.dispatch.Futures;
import akka.dispatch.Mapper;
import akka.dispatch.OnSuccess;
import scala.concurrent.ExecutionContextExecutorService;
import scala.concurrent.Future;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;

/**
 * Futures.sequence
 * Created by liyanxin on 2015/1/9.
 */
public class ComposeFuture {

    public static void main(String args[]) {
        ExecutionContextExecutorService ec = ExecutionContexts.
                fromExecutorService(Executors.newCachedThreadPool());
        List<Future<Integer>> listOfFutureInts = new ArrayList<Future<Integer>>(10);
        for (int i = 0; i < 10; i++) {
            Future<Integer> item = Futures.successful(i);
            listOfFutureInts.add(item);
        }

        // now we have a Future[Iterable[Integer]]
        // Transforms a JIterable[Future[A]] into a Future[JIterable[A]].
        // Useful for reducing many Futures into a single Future.
        /**
         * Future.sequence is taking the
         * Iterable<Future<Integer>> and turning it into a Future<Iterable<Integer>>.
         */
        Future<Iterable<Integer>> futureListOfInts = Futures.sequence(listOfFutureInts, ec);
        // Find the sum of the odd numbers
        Future<Long> futureSum = futureListOfInts.map(
                new Mapper<Iterable<Integer>, Long>() {
                    public Long apply(Iterable<Integer> ints) {
                        long sum = 0;
                        for (Integer i : ints)
                            sum += i;
                        return sum;
                    }
                }, ec);
        futureSum.onSuccess(new OnSuccess<Long>() {
            @Override
            public void onSuccess(Long result) throws Throwable {
                System.out.println(result);
            }
        }, ec);
    }
}
